package src;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author Patrik Mihalcin
 */
public class BondsBruteForce {

	private Context c1;
	private Context c2;
	private List<List<Double>> extentsC1;
	private List<List<Double>> intentsC2;
	private List<List<List<Double>>> extentVariations;
	private List<List<List<Double>>> intentVariations;	
	private List<Bond> bondsFromExtentPointOfView = new ArrayList<Bond>();
	private List<Bond> bondsFromIntentPointOfView = new ArrayList<Bond>();	
	
	public BondsBruteForce(Double[][] relation1, Double[][] relation2, ClosureType closureType, Integer logicDegree) {
		c1 = new Context(logicDegree, relation1);
		c2 = new Context(logicDegree, relation2);
		
		c1.lattice(closureType);
		c2.lattice(closureType);
		
		extentsC1 = c1.getExtents();
		intentsC2 = c2.getIntents();
//		System.out.println("c1 - extents");
//		System.out.println(extentsC1);
//		System.out.println();
//		
//		System.out.println("c2 - intents");
//		System.out.println(intentsC2);		
//		System.out.println();
		
		VariationsWithoutRepetition extentGenerator = new VariationsWithoutRepetition(extentsC1, c2.getAttributesCount());
		extentGenerator.generate();
		extentVariations = extentGenerator.getAllVariations();
		
//		System.out.println("all extent variations");
//		System.out.println();
//		int i = 0;
//		for (List<List<Double>> extentVariation : extentVariations) {
//			System.out.println(++i + ": " + extentVariation);
//		}		
//		System.out.println();
		
		VariationsWithoutRepetition intentGenerator = new VariationsWithoutRepetition(intentsC2, c1.getObjectsCount());
		intentGenerator.generate();
		intentVariations = intentGenerator.getAllVariations();	
		
//		System.out.println("all intent variations");
//		System.out.println();
//		i = 0;
//		for (List<List<Double>> intentVariation : intentVariations) {
//			System.out.println(++i + ": " + intentVariation);
//		}	
//		System.out.println();
		
		for (List<List<Double>> extentVariation : extentVariations) {
			List<List<Double>> transposedVariation = transpose(extentVariation);
			if (intentVariations.contains(transposedVariation)) {
				Bond bond = new Bond(extentVariation, transposedVariation);
				bondsFromExtentPointOfView.add(bond);
			}
		}
		
		for (List<List<Double>> intentVariation : intentVariations) {
			List<List<Double>> transposedVariation = transpose(intentVariation);
			if (extentVariations.contains(transposedVariation)) {
				Bond bond = new Bond(transposedVariation, intentVariation);
				bondsFromIntentPointOfView.add(bond);
			}
		}
	}
	
    private List<List<Double>> transpose(List<List<Double>> fuzzySets) {
    	List<List<Double>> result = new ArrayList<List<Double>>();
    	
    	for (int i = 0; i < fuzzySets.get(0).size(); i++) {
    		List<Double> temp = new ArrayList<Double>();
    		for (int j = 0; j < fuzzySets.size(); j++) {
    			temp.add(fuzzySets.get(j).get(i));
			}
    		result.add(temp);
		}

    	return result;
    }	
    
    public List<Bond> getBondsFromExtentPointOfView() {
		return bondsFromExtentPointOfView;
	}
    
    public List<Bond> getBondsFromIntentPointOfView() {
		return bondsFromIntentPointOfView;
	}
}
